package com.un.ebs.inventory.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.un.ebs.core.common.KeyValueDto;
import com.un.ebs.core.exception.BusinessEntityNotFoundException;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.util.ReportUtils;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.core.util.WebResult;
import com.un.ebs.core.util.WebUtils;
import com.un.ebs.core.validator.NotLessThanZero;
import com.un.ebs.inventory.domain.InventoryNoteExt;
import com.un.ebs.inventory.domain.InventoryNoteItemBySale;
import com.un.ebs.inventory.domain.InventoryNoteItemExt;
import com.un.ebs.inventory.domain.JxcView;
import com.un.ebs.inventory.dto.*;
import com.un.ebs.inventory.enums.InventoryTypeEnum;
import com.un.ebs.inventory.service.InventoryNoteService;
import com.un.ebs.inventory.service.InventoryNoteTypeService;
import com.un.ebs.production.domain.ProductionOrderView;
import com.un.ebs.production.service.ProductionOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liubo
 * @since 2020-05-23
 */
@RestController
@RequestMapping("/inventoryNote")
@Validated
@Api(value = "inventory-note", tags = "库存业务单据")
public class InventoryNoteController {

    @Resource
    private InventoryNoteService service;

    @Resource
    private ProductionOrderService productionOrderService;

    @Resource
    private InventoryNoteTypeService inventoryNoteTypeService;

    @PostMapping("addByIn")
    @ApiOperation(value = "创建入库单")
    public WebResult saveByIn(@RequestBody @Validated InventoryNoteAddDto req) {
        service.addByIn(req);
        return WebUtils.success();
    }

    @PostMapping("addByOut")
    @ApiOperation(value = "创建出库单")
    public WebResult saveByOut(@RequestBody @Validated InventoryNoteAddDto req) {
        service.addByOut(req);
        return WebUtils.success();
    }

    @PostMapping("addByProductionIn")
    @ApiOperation(value = "创建生产入库单")
    public WebResult saveByProductionIn(@RequestParam String productionOrderId, @RequestParam String skuId, @RequestParam String warehouseId, @RequestParam @NotLessThanZero(message = "入库数量不能为零。") Double qty) {
        return WebUtils.success(service.addByProductionIn(productionOrderId, skuId, warehouseId, qty));
    }

    @PostMapping("addSimpleByOut")
    @ApiOperation(value = "销售发货")
    public WebResult saveByOut(@RequestBody @Validated InventoryNoteItemAddDto req) {
        service.addBySaleOut(req.getSaleOrderId(), req.getSkuId(), req.getWarehouseId(), req.getQty(), req.getOutTypeId());
        return WebUtils.success();
    }

    @PostMapping("addPurchaseInByOrder")
    @ApiOperation(value = "创建采购收货单")
    public WebResult addByPurchaseFromOrder(@RequestBody @Validated InventoryNoteByPurchaseDto req) {
        return WebUtils.success(service.addByPurchaseIn(req.getPurchaseOrderId(), req.getWarehouseId(), req.getItems()));
    }

    @PostMapping("addBySaleOut")
    @ApiOperation(value = "创建销售出库单")
    public WebResult saveBySaleOut(@RequestBody @Validated InventoryNoteBySaleOutDto req) {
        service.addBySaleOut(req);
        return WebUtils.success();
    }

    @PostMapping("updateByMove")
    @ApiOperation(value = "创建调拨单")
    public WebResult updateByMove(@RequestBody @Validated InventoryNoteUpdateDto req) {
        req.setNoteTypeId(inventoryNoteTypeService.queryOneByType(InventoryTypeEnum.MOVE_OUT).getId());
        service.update(req);
        return WebUtils.success();
    }

    @PostMapping("update")
    @ApiOperation(value = "修改")
    public WebResult update(@RequestBody @Validated InventoryNoteUpdateDto req) {
        service.update(req);
        return WebUtils.success();
    }

    @PostMapping("submit")
    @ApiOperation(value = "提交")
    public WebResult submit(@RequestParam String id) {
        service.submit(id);
        return WebUtils.success();
    }

    @PostMapping("submitCancel")
    @ApiOperation(value = "提交")
    public WebResult submitCancel(@RequestParam String id) {
        service.submitCancel(id);
        return WebUtils.success();
    }

    @PostMapping("audit")
    @ApiOperation(value = "审核")
    public WebResult audit(@RequestParam String id) {
        service.audit(id);
        return WebUtils.success();
    }

    @PostMapping("auditCancel")
    @ApiOperation(value = "审核撤销")
    public WebResult auditCancel(@RequestParam String id) {
        service.auditCancel(id);
        return WebUtils.success();
    }

    @PostMapping("addBack")
    @ApiOperation(value = "退货，按整单")
    public WebResult addBack(@RequestParam String id) {
        service.addByBack(id);
        return WebUtils.success();
    }

    @PostMapping("addBackByItem")
    @ApiOperation(value = "退货，按明细")
    public WebResult addBackByItem(@RequestBody InventoryNoteBackDto req){
        service.addByBack(req);
        return WebUtils.success();
    }

    @PostMapping("submitAll")
    @ApiOperation(value = "提交")
    public WebResult submitAll() {
//        service.submitAll();
        return WebUtils.success();
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "详情", notes = "根据主键获取单个 InventoryNote")
    public WebResult<InventoryNoteVo> getById(@PathVariable("id") String id) {
        return WebUtils.success(service.queryViewById(id));
    }

    @GetMapping("list")
    @ApiOperation(value = "查询")
    public WebResult<IPage<InventoryNoteExt>> list(@RequestParam(required = false) String searchText,
                                                   @RequestParam(required = false) Boolean auditStatus,
                                                   @RequestParam(required = false) String relationNoteId,
                                                   @RequestParam(required = false) InventoryTypeEnum type,
                                                   @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.query(StringUtils.isNullOrEmpty(searchText) ? null : searchText.trim(), relationNoteId, auditStatus, type, pageSize, pageIndex));
    }

    @GetMapping("listByNoteType")
    @ApiOperation(value = "查询")
    public WebResult<IPage<InventoryNoteExt>> listByNoteType(@RequestParam(required = false) String searchText, @RequestParam(required = false) InventoryTypeEnum type, @RequestParam(required = false) String noteTypeId, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.query(StringUtils.isNullOrEmpty(searchText) ? null : searchText.trim(), type, noteTypeId, pageSize, pageIndex));
    }

    @PostMapping("listByType")
    @ApiOperation(value = "查询，按单据类别")
    public WebResult<IPage<InventoryNoteExt>> listByType(@RequestBody InventoryNoteQueryRequest req) {
        return WebUtils.success(service.query(req));
    }

    @GetMapping("listItem")
    @ApiOperation(value = "查询明细", notes = "根据主键获取单个 InventoryNote")
    public WebResult<IPage<InventoryNoteItemExt>> listItem(@RequestParam String id, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryItemById(id, pageSize, pageIndex));
    }

    @GetMapping("listItemQuery")
    @ApiOperation(value = "查询明细", notes = "根据主键获取单个 InventoryNote")
    public WebResult<IPage<InventoryNoteItemExt>> listItemQuery(@RequestParam(required = false) String searchText,
                                                                @RequestParam InventoryTypeEnum type,
                                                                @RequestParam(required = false) String noteTypeId,
                                                                @RequestParam Integer pageSize,
                                                                @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryItem(StringUtils.isNullOrEmpty(searchText) ? null : searchText.trim(), type, noteTypeId, pageSize, pageIndex));
    }

    @PostMapping("listItemQueryRequest")
    @ApiOperation(value = "查询明细", notes = "根据主键获取单个 InventoryNote")
    public WebResult<IPage<InventoryNoteItemExt>> listItemQueryRequest(@RequestBody InventoryNoteItemQueryRequest req) {
        return WebUtils.success(service.queryItem(req));
    }

    @GetMapping("listItemByNoteTypeId")
    @ApiOperation(value = "查询明细", notes = "根据主键获取单个 InventoryNote")
    public WebResult<IPage<InventoryNoteItemExt>> listItemByNoteTypeId(@RequestParam(required = false) String noteTypeId, @RequestParam String skuId, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryItemExtByNoteTypeId(noteTypeId, skuId, pageSize, pageIndex));
    }

    @GetMapping("listItemByInventoryType")
    @ApiOperation(value = "查询明细", notes = "根据主键获取单个 InventoryNote")
    public WebResult<IPage<InventoryNoteItemExt>> listItemByInventoryType(@RequestParam InventoryTypeEnum type, @RequestParam String skuId, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryItemExtByNoteType(type, skuId, pageSize, pageIndex));
    }

    @GetMapping("listItemEnt")
    @ApiOperation(value = "查询明细", notes = "查询单据中的往来单位")
    public WebResult<List<KeyValueDto>> listItemEnt() {
        return WebUtils.success(service.queryEnt());
    }

    @GetMapping("listJxc")
    @ApiOperation(value = "进销存")
    public WebResult<IPage<JxcView>> listJxc(@RequestParam(required = false) String searchText, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryJxc(StringUtils.isNullOrEmpty(searchText) ? null : searchText.trim(), pageSize, pageIndex));
    }

    @GetMapping("listCheckNote")
    @ApiOperation(value = "查询，盘点单")
    public WebResult<IPage<InventoryNoteExt>> listCheckNote(@RequestParam(required = false) String code,Integer accountYear,Integer accountMonth, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.queryCheckNote(code,accountYear,accountMonth,pageSize,pageIndex));
    }

    @GetMapping("listSaleByCanInvoice")
    @ApiOperation(value = "查询，未开票的销售出库")
    public WebResult<IPage<InventoryNoteItemBySale>> listSaleByCanInvoice(@RequestParam String entId,
                                                                          @RequestParam(required = false) String inventoryNoteCode,
                                                                          @RequestParam(required = false) Integer pageSize,
                                                                          @RequestParam(required = false) Integer pageIndex) {
        return WebUtils.success(service.querySaleCanInvoice(entId,inventoryNoteCode, pageSize, pageIndex));
    }

    @GetMapping("listSale")
    @ApiOperation(value = "查询，发出商品")
    public WebResult<IPage<InventoryNoteItemBySale>> listSale(@RequestParam(required = false) String searchText, @RequestParam String month, @RequestParam(required = false) String entId, @RequestParam Boolean isNotInvoice, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.querySale(searchText, entId, month, isNotInvoice, pageSize, pageIndex));
    }

    @PostMapping("delete/{id}")
    @ApiOperation(value = "删除", notes = "根据主键删除单个 InventoryNote")
    public WebResult delete(@PathVariable("id") String id) {
        service.delete(id);
        return WebUtils.success();
    }

    @GetMapping("print")
    @ApiOperation("打印")
    public void print(@RequestParam String id, HttpServletResponse response) {
        InventoryNoteVo note = service.queryViewById(id);
        if (note == null) {
            throw new BusinessEntityNotFoundException(id, "库存业务单据数据");
        }
        if (StringUtils.isNullOrEmpty(note.getPrintTemplate())) {
            throw new BusinessException(note.getNoteTypeName() + "没有指定打印模板。");
        }

        if (inventoryNoteTypeService.queryOneByType(InventoryTypeEnum.PRODUCTION_BOM_USER).getId().equals(note.getNoteTypeId()) || inventoryNoteTypeService.queryOneByType(InventoryTypeEnum.REPAIR_USER).getId().equals(note.getNoteTypeId())) {
            InventoryNoteByBomUser bomNote = new InventoryNoteByBomUser();
            BeanUtils.copyProperties(note, bomNote);

            ProductionOrderView view = productionOrderService.queryViewByOrderId(note.getRelationNoteId());
            if (view != null) {
                bomNote.setSkuCode(view.getSkuCode());
                bomNote.setSkuName(view.getSkuName());
                bomNote.setQty(view.getProductionQty());
            }

            ReportUtils.print(bomNote, note.getItems(), note.getPrintTemplate(), response);
        } else {
            ReportUtils.print(note, note.getItems(), note.getPrintTemplate(), response);
        }
    }

    @GetMapping("print/check")
    @ApiOperation("打印出库送检单")
    public void printCheck(@RequestParam String id, HttpServletResponse response) {
        InventoryNoteVo note = service.queryViewById(id);
        if (note == null) {
            throw new BusinessEntityNotFoundException(id, "库存业务单据数据");
        }
        ReportUtils.print(note, note.getItems(), "reports/inv_note_out_check.jrxml", response);
    }

    @GetMapping("print/checkIn")
    @ApiOperation("打印入库送检单")
    public void printCheckIn(@RequestParam String id, HttpServletResponse response) {
        InventoryNoteVo note = service.queryViewById(id);
        if (note == null) {
            throw new BusinessEntityNotFoundException(id, "库存业务单据数据");
        }
        ReportUtils.print(note, note.getItems(), "reports/inv_note_in_check.jrxml", response);
    }

}
